package lumis.portal.report;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.GenericGenerator;

import lumis.portal.event.persistence.PortalEventEntityListener;
import lumis.portal.stability.StableMinor;

/**
 * Holds configuration information of a Report.
 * 
 * @stereotype entity
 * @composed 1 - * ReportParameter
 * @navassoc * - 1 ReportType
 * 
 * @since 4.2.0
 * @version $Revision: 13082 $ $Date: 2011-05-27 16:03:12 -0300 (Fri, 27 May 2011) $
 */
@StableMinor(version = "6.0", sinceVersion = "4.2")
@Entity
@Table(name="lum_RepReport")
@GenericGenerator(name="portal-guid", strategy="lumis.portal.dao.hibernate.GuidGenerator")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@EntityListeners(value=PortalEventEntityListener.class)
public class Report 
{
	@Id @GeneratedValue(generator="portal-guid")
	private String id;
	private String name;
	private String description;

	@OneToMany(mappedBy="report", cascade=CascadeType.ALL)
	@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	private Collection<ReportParameter> parameters = new ArrayList<ReportParameter>();

	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="reportTypeId")
	private ReportType reportType;
	
	/**
	 * Returns the identifier for this report.
	 * @return the identifier for this report.
	 * @since 4.2.0
	 */
	public String getId()
	{
		return id;
	}

	/**
	 * Returns the display name for this report.
	 * @return the display name.
	 * @since 4.2.0
	 */
	public String getName()
	{
		return name;
	}

	/**
	 * Sets the display name for this report.
	 * @param the display name.
	 * @since 4.2.0
	 */
	public void setName(String name)
	{
		this.name = name;
	}

	/**
	 * Returns the description for this report.
	 * @return the description.
	 * @since 4.2.0
	 */
	public String getDescription()
	{
		return description;
	}

	/**
	 * Sets the description for this report.
	 * @param description the description.
	 * @since 4.2.0
	 */
	public void setDescription(String description)
	{
		this.description = description;
	}
	
	/**
	 * Returns the report type of this report.
	 * @return the report type.
	 * @since 4.2.0
	 */
	public ReportType getReportType()
	{
		return reportType;
	}

	/**
	 * Sets the report type of this report.
	 * @param reportType the report type.
	 * @since 4.2.0
	 */
	public void setReportType(ReportType reportType)
	{
		this.reportType= reportType;
	}

	/**
	 * Returns an immutable view of the configuration parameters for the Report.
	 * @return an immutable collection of parameters.
	 */
	public Collection<ReportParameter> getParameters()
	{
		return Collections.unmodifiableCollection(parameters);
	}
	
	/**
	 * Adds a parameter in this report.
	 * @return the added parameter object.
	 * @since 4.2.0
	 */
	public ReportParameter addParameter()
	{
		ReportParameter parameter = new ReportParameter();
		parameters.add(parameter);
		parameter.setReport(this);
		return parameter;
	}

	// -- Operations -- //
	
	/**
	 * Removes a parameter from this report.
	 * @param reportParameter the parameter.
	 * @since 4.2.0
	 */
	void removeParameter(ReportParameter reportParameter)
	{
		parameters.remove(reportParameter);
	}
}